﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.DataModel;
using YArchitech.MEP;
using YArchitech.Revit;
using HYFamilyLibDataManager;

namespace YArchitech.Plumbing
{
	public class OperateSegmentFitting
	{
		public OperateSegmentFitting(Document document)
		{
			this.doc = document;
			this.listFS = YJKElementFilter.GetElementByClass(typeof(FamilySymbol), this.doc);
		}

		private FilteredElementCollector GetAllPipeSegment()
		{
			return new HYSystemElementFilter(this.doc).GetElementsByBICategory(BuiltInCategory.OST_PipeSegments);
		}

		private FilteredElementCollector GetAllPipeSchedules()
		{
			return new HYSystemElementFilter(this.doc).GetElementsByBICategory(BuiltInCategory.OST_PipeSchedules);
		}

		private FilteredElementCollector GetAllMaterials()
		{
			return new HYSystemElementFilter(this.doc).GetElementsByBICategory(BuiltInCategory.OST_Materials);
		}

		public PipeType CreatHYPipeTypeByName(string ptName)
		{
			List<Element> elementByClass = YJKElementFilter.GetElementByClass(typeof(PipeType), this.doc);
			if (elementByClass.Count <= 0)
			{
				return null;
			}
			foreach (Element element in elementByClass)
			{
				if (ptName == element.Name)
				{
					return element as PipeType;
				}
			}
			return (elementByClass.First<Element>() as PipeType).Duplicate(ptName) as PipeType;
		}

		public PipingSystemType GetPipingSystemType()
		{
			PipingSystemType result = null;
			FilteredElementIterator elementIterator = new HYSystemElementFilter(this.doc).GetElementsByBICategory(BuiltInCategory.OST_PipingSystem).GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				PipingSystemType pipingSystemType = element as PipingSystemType;
				if (pipingSystemType != null)
				{
					Parameter parameter = pipingSystemType.GetParameter(BuiltInParameter.RBS_SYSTEM_CLASSIFICATION_PARAM);
					if (parameter.AsString() == 16.ToString() || parameter.AsString() == "卫生设备")
					{
						result = pipingSystemType;
						break;
					}
				}
			}
			return result;
		}

		public FamilySymbol GetFamilySymbolByName(string familyName)
		{
			FamilySymbol result = null;
			if (this.listFS.Count <= 0)
			{
				return null;
			}
			foreach (Element element in this.listFS)
			{
				FamilySymbol familySymbol = element as FamilySymbol;
				if (familySymbol != null && familySymbol.Family.Name == "HY_" + familyName)
				{
					result = familySymbol;
					break;
				}
			}
			return result;
		}

		public List<DbFamily> GetDBFamilyList(HYFamilySymbolSign fSymbolSign)
		{
			List<DbFamily> result = null;
			switch (fSymbolSign)
			{
			case HYFamilySymbolSign.Elbow:
				result = this.plumbDR.GetFamilyAllInfoList("水管弯头");
				break;
			case HYFamilySymbolSign.Tee:
				result = this.plumbDR.GetFamilyAllInfoList("水管三通");
				break;
			case HYFamilySymbolSign.Cross:
				result = this.plumbDR.GetFamilyAllInfoList("水管四通");
				break;
			case HYFamilySymbolSign.SBend:
				result = this.plumbDR.GetFamilyAllInfoList("S型存水弯");
				break;
			case HYFamilySymbolSign.PBend:
				result = this.plumbDR.GetFamilyAllInfoList("P型存水弯");
				break;
			case HYFamilySymbolSign.CleanMouth:
				result = this.plumbDR.GetFamilyAllInfoList("清扫口");
				break;
			case HYFamilySymbolSign.VentilationCap:
				result = this.plumbDR.GetFamilyAllInfoList("通气帽");
				break;
			case HYFamilySymbolSign.FloorDrain:
				result = this.plumbDR.GetFamilyAllInfoList("地漏");
				break;
			case HYFamilySymbolSign.CheckMouth:
				result = this.plumbDR.GetFamilyAllInfoList("检查口");
				break;
			}
			return result;
		}

		public FamilySymbol LoadFamilySymbolByName(string familyName, HYFamilySymbolSign fSymbolSign)
		{
			FamilySymbol familySymbol = null;
			familySymbol = this.GetFamilySymbolByName(familyName);
			if (familySymbol != null)
			{
				return familySymbol;
			}
			List<DbFamily> dbfamilyList = this.GetDBFamilyList(fSymbolSign);
			if (dbfamilyList == null || dbfamilyList.Count <= 0)
			{
				return familySymbol;
			}
			foreach (DbFamily dbFamily in dbfamilyList)
			{
				if (!(dbFamily.Name != familyName))
				{
					using (List<FamilySymbol>.Enumerator enumerator2 = dbFamily.LoadInSubTrans(this.doc).GetSymbols().GetEnumerator())
					{
						if (enumerator2.MoveNext())
						{
							familySymbol = enumerator2.Current;
						}
					}
				}
			}
			return familySymbol;
		}

		public PipeType GetPipeTypeByTypeName(string typeName)
		{
			List<Element> elementByClass = YJKElementFilter.GetElementByClass(typeof(PipeType), this.doc);
			if (elementByClass.Count <= 0)
			{
				return null;
			}
			foreach (Element element in elementByClass)
			{
				if (typeName == element.Name)
				{
					return element as PipeType;
				}
			}
			return elementByClass[0] as PipeType;
		}

		public PipeScheduleType GetPipeScheduleByKey(string scheduleName)
		{
			PipeScheduleType pipeScheduleType = null;
			FilteredElementIterator elementIterator = this.GetAllPipeSchedules().GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				PipeScheduleType pipeScheduleType2 = element as PipeScheduleType;
				if (pipeScheduleType2 != null)
				{
					pipeScheduleType = pipeScheduleType2;
					if (scheduleName != "" && pipeScheduleType2.Name == scheduleName)
					{
						return pipeScheduleType2;
					}
				}
			}
			return pipeScheduleType.Duplicate(scheduleName) as PipeScheduleType;
		}

		public Material CreatHYMaterial(string materialName, string nameKey)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
			filteredElementCollector.OfCategory(BuiltInCategory.OST_Materials);
			FilteredElementIterator elementIterator = filteredElementCollector.GetElementIterator();
			elementIterator.Reset();
			Material material = null;
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				Material material2 = element as Material;
				if (material2 != null)
				{
					material = material2;
					if (material2.Name == materialName)
					{
						return material;
					}
					if (nameKey != "" && material2.Name.Contains(nameKey))
					{
						material = material2;
						break;
					}
				}
			}
			return material.Duplicate(materialName);
		}

		public PipeSegment CreatHYPipeSegment(HYMaterial hyMaterial)
		{
			PipeSegment pipeSegment = this.JudgePSBeExist(hyMaterial.Segment, hyMaterial.Schedule);
			if (pipeSegment == null)
			{
				Material material = this.CreatHYMaterial(hyMaterial.Segment, "PVC");
				PipeScheduleType pipeScheduleByKey = this.GetPipeScheduleByKey(hyMaterial.Schedule);
				ICollection<MEPSize> collection = new List<MEPSize>();
				foreach (HYPipeSpecification hypipeSpecification in hyMaterial.Specifications)
				{
					double num = (double)hypipeSpecification.DN / 304.8;
					double num2 = hypipeSpecification.Diameter / 304.8;
					double num3 = (hypipeSpecification.Diameter - hypipeSpecification.Thickness) / 304.8;
					MEPSize item = new MEPSize(num, num3, num2, true, true);
					collection.Add(item);
				}
				pipeSegment = PipeSegment.Create(this.doc, material.Id, pipeScheduleByKey.Id, collection);
			}
			return pipeSegment;
		}

		public bool SetPipeFitting(PipeType pipeType, int num, ElementId elemId)
		{
			RoutingPreferenceManager routingPreferenceManager = pipeType.RoutingPreferenceManager;
			UnifiedModified.SetSegmentFitting(pipeType, num, elemId, pipeType.Name);
			return true;
		}

		private PipeSegment JudgePSBeExist(string segmentName, string scheduleName)
		{
			FilteredElementIterator elementIterator = this.GetAllPipeSegment().GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				if (element != null)
				{
					PipeSegment pipeSegment = element as PipeSegment;
					if (pipeSegment != null)
					{
						string b = segmentName + " - " + scheduleName;
						string b2 = segmentName + " _ " + scheduleName;
						if (pipeSegment.Name == b || pipeSegment.Name == b2)
						{
							return pipeSegment;
						}
					}
				}
			}
			return null;
		}

		public PipeSegment GetPipeSegmentByPipeTypeName(string pipeTypeName)
		{
			RoutingPreferenceManager routingPreferenceManager = this.GetPipeTypeByTypeName(pipeTypeName).RoutingPreferenceManager;
			return this.doc.GetElementById(routingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)0, 0).MEPPartId) as PipeSegment;
		}

		private Document doc;

		private List<Element> listFS;

		private PlumbingDataReader plumbDR;
	}
}
